package com.hashcoding.eyes.ui.adapter;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.hashcoding.eyes.EyesApplication;
import com.hashcoding.eyes.R;
import com.hashcoding.eyes.module.utils.NetworkUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * ListAdapter基类
 *
 * @author markmjw
 * @date 2014-10-29
 */
public abstract class BaseListAdapter<T> extends BaseAdapter {
    public static final int STATE_EMPTY_ITEM = 0;
    public static final int STATE_LOAD_MORE = 1;
    public static final int STATE_LOADING = 2;
    public static final int STATE_NO_MORE = 3;
    public static final int STATE_NO_DATA = 4;
    public static final int STATE_LESS_ONE_PAGE = 5;
    public static final int STATE_NETWORK_ERROR = 6;

    protected int mState = STATE_LESS_ONE_PAGE;

    protected Context mContext;

    protected int mLoadMoreText;
    protected int mLoadFinishText;

    protected List<T> mList = new ArrayList<>();

    protected LayoutInflater mInflater;

    public BaseListAdapter(Context context) {
        mContext = context;
        mLoadMoreText = R.string.loading;
        mLoadFinishText = R.string.loading_no_more;
        mInflater = LayoutInflater.from(mContext);
    }

    public void setState(int state) {
        mState = state;
    }

    public int getState() {
        return mState;
    }

    /**
     * 设置数据列表.
     *
     * @param data the new list
     */
    public void setList(List<T> data) {
        if (mList == data) {
            return;
        }
        if (mList == null) {
            mList = createList();
        }

        if (data == null) {
            return;
        }

        if (mList.size() > 0) {
            mList.clear();
        }
        mList.addAll(data);

        notifyDataSetChanged();
    }

    /**
     * 获取数据列表
     */
    public List<T> getList() {
        return mList;
    }

    /**
     * 添加数据列表.
     *
     * @param data the data list
     */
    public void addList(List<T> data) {
        if (data != null) {
            if (mList == null) {
                mList = createList();
            }
            mList.addAll(data);

            notifyDataSetChanged();
        }
    }

    /**
     * 增加一项数据数据
     *
     * @param item
     */
    public void addItemFirst(T item) {
        if (item != null && mList != null) {
            mList.add(0, item);
            notifyDataSetChanged();
        }
    }

    /**
     * 增加一项数据数据
     *
     * @param item
     */
    public void addItem(T item) {
        if (item != null && mList != null) {
            mList.add(item);
            notifyDataSetChanged();
        }
    }

    /**
     * 删除指定数据
     *
     * @param item
     */
    public void removeItem(T item) {
        if (item != null && mList != null) {
            mList.remove(item);
            notifyDataSetChanged();
        }
    }

    /**
     * 获得当前的数据数目
     *
     * @return the data size
     */
    public int getDataSize() {
        int size = 0;
        if (mList != null) {
            size = mList.size();
        }
        return size;
    }

    /**
     * 清空adapter的数据
     */
    public void clear() {
        if (mList != null) {
            mList.clear();
            notifyDataSetChanged();
        }
    }

    public void setLoadMoreText(int loadMoreText) {
        mLoadMoreText = loadMoreText;
    }

    public void setLoadFinishText(int loadFinishText) {
        mLoadFinishText = loadFinishText;
    }

    protected Drawable getLoadMoreBackground() {
        return null;
    }

    /**
     * 创建List，子类可覆盖实现
     *
     * @return
     */
    protected List<T> createList() {
        return new ArrayList<>();
    }

    public boolean canLoadMore() {
        return STATE_LOAD_MORE == mState || STATE_NETWORK_ERROR == mState;
    }

    @Override
    public int getCount() {
        switch (getState()) {
            case STATE_EMPTY_ITEM:
                return getDataSize() + 1;

            case STATE_NETWORK_ERROR:
            case STATE_LOAD_MORE:
            case STATE_LOADING:
                return getDataSize() + 1;

            case STATE_NO_DATA:
                return 0;

            case STATE_NO_MORE:
                return getDataSize() + 1;

            case STATE_LESS_ONE_PAGE:
                return getDataSize();

            default:
                break;
        }

        return getDataSize();
    }

    @Override
    public boolean isEmpty() {
        return getDataSize() <= 0;
    }

    @Override
    public T getItem(int position) {
        if (position >= 0 && position < mList.size()) {
            return mList.get(position);
        } else {
            return null;
        }
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        boolean state = STATE_EMPTY_ITEM == getState()
                || STATE_LOAD_MORE == getState()
                || STATE_LOADING == getState()
                || STATE_NETWORK_ERROR == getState()
                || STATE_NO_MORE == getState();
        if (state && position == getCount() - 1) {
            // 最后一条
            LinearLayout layout = (LinearLayout) mInflater.inflate(R.layout.vw_load_more, null);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                layout.setBackground(getLoadMoreBackground());
            } else {
                layout.setBackgroundDrawable(getLoadMoreBackground());
            }

            ProgressBar progress = (ProgressBar) layout.findViewById(R.id.load_more_progress);
            TextView text = (TextView) layout.findViewById(R.id.load_more_text);

            switch (getState()) {
                case STATE_LOADING:
                case STATE_LOAD_MORE:
                    layout.setVisibility(View.VISIBLE);
                    progress.setVisibility(View.VISIBLE);
                    text.setVisibility(View.VISIBLE);
                    text.setText(mLoadMoreText);
                    break;

                case STATE_NO_MORE:
                    layout.setVisibility(View.VISIBLE);
                    progress.setVisibility(View.GONE);
                    text.setVisibility(View.VISIBLE);
                    text.setText(mLoadFinishText);
                    break;

                case STATE_EMPTY_ITEM:
                    progress.setVisibility(View.GONE);
                    layout.setVisibility(View.GONE);
                    text.setVisibility(View.GONE);
                    break;

                case STATE_NETWORK_ERROR:
                    layout.setVisibility(View.VISIBLE);
                    progress.setVisibility(View.GONE);
                    text.setVisibility(View.VISIBLE);
                    if (NetworkUtil.isConnected(EyesApplication.gContext)) {
                        text.setText(R.string.error_tip);
                    } else {
                        text.setText(R.string.no_network);
                    }
                    break;

                default:
                    progress.setVisibility(View.GONE);
                    layout.setVisibility(View.GONE);
                    text.setVisibility(View.GONE);
                    break;
            }
            return layout;
        }
        return getItemView(position, convertView, parent);
    }

    protected abstract View getItemView(int position, View convertView, ViewGroup parent);
}
